<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    - 变量提升(`变量声明提升`)
      - 变量声明语句会提升到当前作用域的最前面执行
      - 在变量声明语句之前, 就可以访问到这个变量(undefined)
    - 函数提升(`函数声明提升`)
      - 函数声明语句提升到当前作用域的最前面执行
      - 在函数声明语句之前, 就可以执行该函数
    - 原因: 简单来说就是在执行全局代码和函数前会进行`预解析/处理`
      - 将var变量声明放在最前面执行
      - 将function函数声明放在最前面执行
    - 注意
      - const / let / class 没有提升
      - var 变量 / function 函数声明 才有提升
    */
    /* 
    var a1
    function a2() {
      
    }

    console.log(a1)
    console.log(a2)  // a2()

    a1 = 3
    
    */

    console.log(a1)
    console.log(a2)

    var a1 = 3
    function a2() { //  函数声明定义函数
      
    }

    console.log(a3)

    let a3 = function () {
      
    }
    const a4 = {}
    class a5 {

    }

    // 函数表达式 定义函数
    var a6 = function () {};

    (function () {})();  // 立即调用函数表达式 IIFE

    // function () {}  这是一个表达式, 不能单独存在, 必须与其它运算结果起来形成一条语句

    // fn(3)
    // 表达式: 数据值  3/'abc'/true/{} /    值与运算的组合  3 + 1   变量  变量与运算的组合
    // {{表达式}}  {{3}}  {{a}}
  </script>
</body>
</html>